package com.ruoyi.web.controller.v1;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.LoginType;
import com.ruoyi.common.utils.PropertiesUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpClientUtils;
import com.ruoyi.framework.config.nopassword.UserToken;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.ROrg;
import com.ruoyi.system.service.*;
import com.ruoyi.web.controller.eventbus.EventBusContext;
import com.ruoyi.web.controller.eventbus.bigdata.SearchEvent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

/**
 * v1版本接口
 * @author ruoyi
 */
@Controller
@Api(tags = {"v1版本接口"})
@RequestMapping("")
public class ApiController extends BaseController {

    @Autowired
    private IROrgService orgService;
    @Autowired
    private ISysUserService userService;

    @Autowired
    private EventBusContext eventBusContext;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private ISysRoleService sysRoleService;

    private static Integer loginPre = 0;

    @ApiOperation("登录认证接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ssoToken", value = "认证token", defaultValue = "a93f9a21-a367-43d3-8116-4deec42808a1", required = true),

    })
    @GetMapping ("/ssoLogin")
    public String ajaxLogin(String  ssoToken,
                            ModelMap mmap){
        String authLoginUrl = PropertiesUtils.getInstance().get("auth_login_url");
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("ssoToken",ssoToken);
            String authCode = PropertiesUtils.getInstance().get("auth_code");
            params.put("authCode",authCode);
            String ssoAuthUrl = PropertiesUtils.getInstance().get("sso_auth_url");
            logger.info("登录认证接口,authLoginUrl:{},authCode:{},ssoAuthUrl:{}",authLoginUrl,authCode,ssoAuthUrl);
            String  source = HttpClientUtils.sendPost(ssoAuthUrl,params);
            logger.info("登录认证接口,请求验证用户信息结果：source:{}",source);
            JSONObject jsonObject = JSONObject.parseObject(source);
            Integer code = jsonObject.getInteger("code");
            String userName = "";
            String deptName = "";
            Long orgID = null;
            if(code == 0){
                String data = jsonObject.getString("data");
                JSONObject jsonObject1 = JSONObject.parseObject(data);
                userName = jsonObject1.getString("username");
                if(StringUtils.isNotBlank(jsonObject1.getString("deptCode"))){
                    orgID = Long.valueOf(jsonObject1.getString("deptCode"));
                }
                deptName = jsonObject1.getString("deptName");
            }
//            String userName = "admin";
            UserToken token = new UserToken(userName, LoginType.NOPASSWD);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            if(StringUtils.isNotEmpty(userName)){
                SysUser sysUser = userService.selectUserByLoginName(userName);
                if(Objects.nonNull(sysUser)){
                    SearchEvent searchEvent = new SearchEvent();
                    if(Objects.isNull(orgID)){
                        orgID = sysUser.getDept().getDeptId();
                    }
                    searchEvent.setOrgId(orgID);
                    if(loginPre==0){
                        eventBusContext.fireAsyncEvent(searchEvent);
                        loginPre++;
                    }
                }
            }
            mmap.put("version", RuoYiConfig.getVersion());
            SysUser sysUser = getSysUser();
            String userDeptName = sysUser.getDept().getDeptName();
            List<SysDictData> dept_name = dictTypeService.selectDictDataByType("fx_org");
            List<SysDictData> collect = dept_name.stream().filter(o -> o.getDictLabel().equals(userDeptName)).collect(Collectors.toList());
            ROrg ROrg = new ROrg();
            if(!collect.isEmpty()){
                ROrg.setName(deptName);
            }
            List<ROrg> rOrgs = orgService.selectROrgList(ROrg);
            mmap.put("rOrgs", rOrgs);
            ROrg rOrg = orgService.selectROrgById(orgID);
            mmap.put("org", Objects.isNull(rOrg)?new ROrg():rOrg);
        } catch (Exception e) {
            logger.error("登录认证接口异常信息："+e.getMessage());
            mmap.put("authLoginUrl", authLoginUrl);
            return "login";
        }
        return "main";
    }


    @ApiOperation("业务系统登出接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ssoToken", value = "认证token", defaultValue = "a93f9a21-a367-43d3-8116-4deec42808a1", required = true),
    })
    @PostMapping ("/ssoLogOut")
    @ResponseBody
    public AjaxResult ssoLogOut(String  ssoToken
    ){
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("ssoToken",ssoToken);
            String authCode = PropertiesUtils.getInstance().get("auth_code");
            params.put("authCode",authCode);
            String ssoLogoutUrl = PropertiesUtils.getInstance().get("sso_logout_url");
            logger.info("业务系统登出接口,authCode:{},ssoAuthUrl:{}",authCode,ssoLogoutUrl);
            String  source = HttpClientUtils.sendPost(ssoLogoutUrl,params);
            logger.info("业务系统登出接口,调用平台退出接口：source:{}",source);
            JSONObject jsonObject = JSONObject.parseObject(source);
            Integer code = jsonObject.getInteger("code");
            if(code == 0){
                Subject subject = SecurityUtils.getSubject();
                subject.logout();
            }
        } catch (Exception e) {
            logger.error("业务系统登出异常信息："+e.getMessage());
            return AjaxResult.success("登出失败："+e.getMessage(),false);
        }
        return AjaxResult.success("登出成功",true);
    }


    @ApiOperation("组织机构同步接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "机构名称", defaultValue = "咸阳", required = true),
            @ApiImplicitParam(name = "code", value = "机构编码", defaultValue = "4", required = true),
            @ApiImplicitParam(name = "type", value = "机构类型", defaultValue = "", required = false),
            @ApiImplicitParam(name = "parentCode", value = "上级机构编码", defaultValue = "0", required = true),
            @ApiImplicitParam(name = "deleted", value = "是否删除", defaultValue = "false", required = true),


    })
    @PostMapping ("/sysData/sysOrg")
    @ResponseBody
    public AjaxResult sysOrg(String  name, String  code,String  type,String  parentCode,
                             String  deleted ){
        try {
            Long deptId = Long.valueOf(code);
            SysDept dept = new SysDept();
            dept.setParentId(Long.valueOf(parentCode));
            dept.setDeptName(name);
            dept.setDeptId(deptId);
            if(Boolean.valueOf(deleted)){
                if (deptService.selectDeptCount(deptId) > 0)
                {
                    return AjaxResult.warn("存在下级部门,不允许删除");
                }
                if (deptService.checkDeptExistUser(deptId))
                {
                    return AjaxResult.warn("部门存在用户,不允许删除");
                }
//                deptService.checkDeptDataScope(deptId);
                return toAjax(deptService.deleteDeptById(deptId));
            }else{
                dept.setOrderNum(1);
                dept.setStatus("0");
                SysDept sysDept1 = deptService.selectDeptById(deptId);
                if(Objects.isNull(sysDept1)){
                    if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
                    {
                        return error("新增部门'" + dept.getDeptName() + "'失败，部门名称已存在");
                    }
                    dept.setCreateBy(getLoginName());
                    return toAjax(deptService.insertDept(dept));
                }else{
//                    deptService.checkDeptDataScope(deptId);
                    if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
                    {
                        return error("修改部门'" + dept.getDeptName() + "'失败，部门名称已存在");
                    }
                    else if (dept.getParentId().equals(deptId))
                    {
                        return error("修改部门'" + dept.getDeptName() + "'失败，上级部门不能是自己");
                    }
                    else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
                    {
                        return AjaxResult.error("该部门包含未停用的子部门！");
                    }
                    dept.setUpdateBy(getLoginName());
                    return toAjax(deptService.updateDept(dept));

                }
            }
        } catch (Exception e) {
            logger.error("组织机构同步异常信息："+e.getMessage());
            return AjaxResult.error("组织机构同步异常信息："+e.getMessage());
        }
    }

    @ApiOperation("系统用户同步接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户账户", defaultValue = "test", required = true),
            @ApiImplicitParam(name = "nickname", value = "用户姓名", defaultValue = "测试", required = false),
            @ApiImplicitParam(name = "phone", value = "手机号", defaultValue = "16618888888", required = false),
            @ApiImplicitParam(name = "deptCode", value = "所属机构编码", defaultValue = "202", required = true),
            @ApiImplicitParam(name = "stateId", value = "0正常 1 删除", defaultValue = "0", required = true),
            @ApiImplicitParam(name = "deleted", value = "是否删除 true是  false  否", defaultValue = "false", required = true),


    })
    @PostMapping ("/sysData/sysUser")
    @ResponseBody
    public AjaxResult sysUser(String  username, String  nickname,String  phone,String  deptCode,
                            String stateId, String  deleted ){
        try {
            SysUser sysUser = userService.selectUserByLoginName(username);
            SysUser user = new SysUser ();
            user.setUserName(nickname);
            user.setLoginName(username);
            user.setPhonenumber(phone);
            user.setDeptId(Long.valueOf(deptCode));
            user.setStatus(stateId);
            if(Boolean.valueOf(deleted)){
                String ids = "";
                if(Objects.isNull(sysUser)){
                    return error("用户不存在");
                }else{
                    ids = sysUser.getUserId().toString();
                }
                if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
                {
                    return error("当前用户不能删除");
                }
                return toAjax(userService.deleteUserByIds(ids));
            }else{
                if(Objects.isNull(sysUser)){
                    if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user)))
                    {
                        return error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
                    }
                    else if (StringUtils.isNotEmpty(user.getPhonenumber())
                            && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
                    {
                        return error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
                    }
                    user.setSalt(ShiroUtils.randomSalt());
                    user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
                    user.setCreateBy(getLoginName());
                    SysRole common = sysRoleService.getRoleByKey("common");
                    Long[] roleIds = new Long[]{2L};
                    if(Objects.nonNull(common)&&Objects.nonNull(common.getRoleId())){
                         roleIds = new Long[]{common.getRoleId()};
                        user.setRoleIds(roleIds);
                    }
                    return toAjax(userService.insertUser(user));
                }else{
                    Long userId = sysUser.getUserId();
                    user.setUserId(userId);
                    user.setLoginName(null);
                    user.setUpdateBy(getLoginName());
                    userService.updateUserInfo(user);
                    AuthorizationUtils.clearAllCachedAuthorizationInfo();
                    return toAjax(userService.updateUser(user));
                }
            }
        } catch (Exception e) {
            logger.error("系统用户同步接口异常信息："+e.getMessage());
            return error("系统用户同步接口异常信息："+e.getMessage());
        }
    }
}
